package com.yami.shop.mystery.common.listener;

import com.yami.shop.bean.enums.EsOperationType;
import com.yami.shop.bean.enums.ProdType;
import com.yami.shop.bean.event.EsMysteryBoxStockUpdateEvent;
import com.yami.shop.bean.event.EsMysteryBoxUpdateEvent;
import com.yami.shop.bean.event.EsProductUpdateEvent;
import com.yami.shop.bean.model.ProdExtension;
import com.yami.shop.bean.model.Product;
import com.yami.shop.bean.model.Sku;
import com.yami.shop.bean.model.SkuStock;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.mystery.common.model.MysteryBoxExtension;
import com.yami.shop.mystery.common.service.MysteryBoxExtensionService;
import com.yami.shop.service.*;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 盲盒库存更新（新增扣除商品库存、活动结束和下架退回商品库存）
 * @author wxf
 * @date 2023/6/8 18:13
 */
@Component("mysteryBoxStockUpdateListener")
@AllArgsConstructor
@Slf4j
public class MysteryBoxStockUpdateListener {

    private final ProdExtensionService prodExtensionService;

    private final SkuService skuService;

    private final SkuStockService skuStockService;

    private final ProductService productService;

    private final ProdParameterService prodParameterService;

    private final ApplicationEventPublisher eventPublisher;

    private final MysteryBoxExtensionService mysteryBoxExtensionService;


    @EventListener(EsMysteryBoxStockUpdateEvent.class)
    public void esMysteryBoxStockUpdateListener(EsMysteryBoxStockUpdateEvent event) {

        EsOperationType esOperationType = event.getEsOperationType();
        List<SkuStock> skuStockList = event.getIds();
        Long mysteryBoxId = event.getMysteryBoxId();
        List<SkuStock> success = new ArrayList<>(); //存储成功的，当有异常时，得回退
        // 批量更新商品库存（盲盒保存扣除商品库存）
        if (Objects.equals(esOperationType, EsOperationType.UPDATE_BATCH)) {

            for (SkuStock stock : skuStockList) {
                try {
                    singleDeductStock(mysteryBoxId, stock);
                    success.add(stock);
                } catch (Exception e) {
                    log.error(e.getMessage());
                    event.setReuslt(e.getMessage());
                    failureRollback(mysteryBoxId,success);
                    return;
                }
            }

        }// 批量更新商品库存（盲盒下架、活动结束回退商品库存）
        else if (Objects.equals(esOperationType, EsOperationType.DELETE_BATCH)) {

            for (SkuStock stock : skuStockList) {
                singleRollbackStock(mysteryBoxId, stock);
            }
        }
    }

    /**
     *  单个扣除库存
     *
     * @param mysteryBoxId
     * @param stock
     */
    private void singleDeductStock(Long mysteryBoxId, SkuStock stock) {
        Sku sku = new Sku();
        sku.setSkuId(stock.getSkuId());
        sku.setStocks(stock.getLockStock());
        if (skuStockService.updateStocksAndLockStock(sku) < 0) {
            // 商品库存不足，不能参加盲盒活动
            throw new YamiShopBindException("盲盒扣除商品" + stock.getProdId() + "库存不足, 商品可用库存：" + stock.getStocks() + " 盲盒扣除库存：" + stock.getLockStock());
        }
        updateProdSku(mysteryBoxId, stock, ProdType.PROD_TYPE_BOX.value());
    }

    /**
     *  单个回退盲盒库存和商品库存
     *
     * @param mysteryBoxId
     * @param stock
     */
    private void singleRollbackStock(Long mysteryBoxId, SkuStock stock) {

        MysteryBoxExtension extension = mysteryBoxExtensionService.getById(stock.getStockId());
        extension.setStocks(stock.getLockStock());
        mysteryBoxExtensionService.rollbackStocks(extension);
        Sku sku = new Sku();
        sku.setSkuId(stock.getSkuId());
        sku.setStocks(stock.getLockStock());
        if (skuStockService.rollbackStocksAndLockStock(sku) < 0) {
            // 商品库存不足，不能参加盲盒活动
            throw new YamiShopBindException("盲盒回退商品" + stock.getProdId() + "库存失败, 商品可用库存：" + stock.getStocks() + " 盲盒回退库存：" + stock.getLockStock());
        }
        updateProdSku(mysteryBoxId, stock, ProdType.PROD_TYPE_NORMAL.value());
    }

    /**
     *  回退已成功的库存
     *
     * @param mysteryBoxId
     * @param success
     */
    private void failureRollback(Long mysteryBoxId, List<SkuStock> success) {
        for (SkuStock stock : success) {
            Sku sku = new Sku();
            sku.setSkuId(stock.getSkuId());
            sku.setStocks(stock.getLockStock());
            if (skuStockService.rollbackStocksAndLockStock(sku) < 0) {
                // 商品库存不足，不能参加盲盒活动
                throw new YamiShopBindException("盲盒回退商品" + stock.getProdId() + "库存失败, 商品可用库存：" + stock.getStocks() + " 盲盒回退库存：" + stock.getLockStock());
            }
            updateProdSku(mysteryBoxId, stock, ProdType.PROD_TYPE_NORMAL.value());
        }
    }

    /**
     *  更新商品库存信息
     *
     * @param mysteryBoxId
     * @param stock
     * @param prodType
     */
    private void updateProdSku(Long mysteryBoxId, SkuStock stock, Integer prodType) {

        skuService.removeSkuCacheBySkuId(stock.getSkuId(), stock.getProdId());
        prodExtensionService.updateProdStocksAndLockStock(stock.getProdId());
        // 更新商品信息
        Product product = new Product();
        product.setActivityId(mysteryBoxId);
        product.setProdType(prodType);
        product.setProdId(stock.getProdId());
        productService.updateById(product);

        productService.removeProdCacheByProdId(stock.getProdId());
        prodParameterService.removeCacheByProdId(stock.getProdId());
        eventPublisher.publishEvent(new EsProductUpdateEvent(stock.getProdId(), null, EsOperationType.UPDATE));
    }
}
